/**
 * 事件工具模块
 *
 * 	1. 分布式事件
 * 	2. 事件化对象
 *
 * 使用：模块间全局通信
 *
 * @author li.xiaomei
 *
 */

//静态变量
var UNDEFINED = void 0, //[ void 0 === undefined ]
	FALSE = false,
	NULL = null,

	//全局变量存储在局部变量中
	__array__ = Array.prototype, 
	slice = __array__.slice,
	toString = Object.prototype.toString;

//工具类
var utils = {
	//纯对象
	isPlainObj: function(obj){
		return (toString.call(obj) === '[object Object]' 
				&& Object.getPrototypeOf(obj) == Object.prototype 
				&& obj!=null && obj != obj.window);
	},
	isArray: function(arr){
		return toString.call(arr) === '[object Array]';
	},

	_extend: function(target, source, deep){
		var self = this;

		for(var key in source) {
			if(deep && (self.isPlainObj(source[key]) || self.isArray(source[key]))) {
				if(self.isPlainObj(source[key]) && !self.isPlainObj(target[key])) {
					target[key] = {};
				}

				if(self.isArray(source[key]) && !self.isArray(target[key])) {
					target[key] = [];
				}

				self._extend(target[key], source[key], deep);
			}else if(typeof source[key] !== 'undefined') {
				target[key] = source[key];
			}
		}
	},

	extend: function(target){
		var self = this;
		var deep, args = slice.call(arguments, 1);

		if(typeof target === 'boolean') {
			deep = target;
			target = args.shift();
		}

		args.forEach(function(arg){
			self._extend(target, arg, deep);
		});

		return target;
	}
};

//func只执行一次【闭包】
function _once(func){
	var ran = FALSE,
		memo;

	return function(){
		if(ran) return memo;

		ran = TRUE;

		memo = func.apply(this, arguments);
		func = undefined;

		return memo;
	}
}

var triggerEvents = function(events, args){
	var ev,
		i = -1,
		l = events.length,
		ret = 1; 

	//return false之后的函数不执行
	while(++i < l && ret){
		ev = events[i];
		ret &= (ev.callback.apply(ev.ctx, args)!== false)
	}

	return !!ret;
};

var moEvent = {
	on: function(name, callback, context){
		(!this.events || this.events = {});
		(!this._events[name] || this._events[name] = []);

		var events = this._events[name];

		//将数据做一层包装
		events.push({
			callback: callback,
			context: context,
			ctx: context || this
		});

		//支持链式调用
		return this;
	},

	once: function(name, callback, context){
		var self = this;
		var once = _once(function(){
			//取消监听
			self.off(name, once);
			//执行回调函数
			callback.apply(this, arguments);
		});

		//保留原始回调函数
		once._callback = callback;

		return this.on(name, once, context);
	},

	off: function(name, callback, context){
		var retain,
			ev,
			events,
			names,
			i,
			l,
			j,
			k;

		if(!name && !callback && !context){
			this._events = undefined;

			return this;
		}

		names = name ? [name] : keys(this._events);

		for(i=0, l = names.length; i<l; i++){
			name = names[i];
			events = this._events[name];

			if(events){
				this._events[name] = retain = [];
				if(callback || context){
					for(j=0,k=events.length; j<k;j++){
						ev = events[j];

						if ((callback && callback !== ev.callback && callback !== ev.callback._callback) ||
	                            (context && context !== ev.context)) {
	                            retain.push(ev);
	                        }
					}
				}
				if (!retain.length) delete this._events[name];
			}
		}

		return this;
	},

	fire: function(name){
		if(!this._events) return this;

		var args = slice.call(arguments, 1),
			events = this._events[name],
			allEvents = this._events.all,
			ret = 1;

		if(events){
			ret &= triggerEvents(events, args);
		}

		if(allEvents && ret){
			ret &= triggerEvents(allEvents, args);
		}

		return !!ret;
	}

};


//Object.create
function _createEventManager(){

	var EM = function(){}

	utils.extend(EM.prototype, moEvent);

	return new EM();
}

//兼容常用模块标准
if(typeof module !== 'undefined' && module.exports) {

	module.exports = _createEventManager;

} else if(typeof define === 'function' && define.amd) {

	define([], function(){
		return _createEventManager;
	});

} else {

	window.subEvent = _createEventManager;

}

